package ar.com.binarit.entities

import ar.com.binarit.Person

class Viaje {

	Person usuarioCreador

	String origen
	String destino
	String locationOrigen
	String locationDestino
	List lugaresDePaso

	Evento evento

	Date fechaSalida
	Date fechaRetorno
	Date fechaFinalizacion
	Date fechaPublicacion
	Date fechaEliminacion

	String horaSalida
	String minutoSalida
	String horaRetorno
	String minutoRetorno

	boolean idaYVuelta

	BigDecimal precioAsiento
	int asientosDisponibles

	String detalle

	Estado estado
	
	String distancia
	Integer distanciaValor
	Integer tiempo
	
	static transients = ['distancia', 'distanciaValor', 'tiempo']

	static belongsTo = ar.com.binarit.Person
	static hasMany = [hinchas : Person, misViajes: Person, pagos:PagoUsuario,comentarios:Comentario]

//	static mappedBy = [viajesQueParticipo:"hinchas"]
	
	static constraints = {
		origen (nullable: false)
		evento (nullable: false)
		locationOrigen (nullable: true)
		locationDestino (nullable: true)
		lugaresDePaso(nullable: true)
		estado (nullable: true)
		destino (nullable:true)
		horaSalida (nullable:true)
		minutoSalida (nullable:true)
		horaRetorno (nullable:true)
		minutoRetorno (nullable:true)
		hinchas(nullable: true)
		pagos(nullable:true)
		usuarioCreador(nullable: false)
		fechaEliminacion(nullable: true)
		fechaPublicacion(nullable: true)
	}

	static mapping = { 
		detalle type: 'text'
		misViajes joinTable: "person_viaje_s"
//		version false
	}

	public Viaje(){
		lugaresDePaso = new ArrayList()
		estado = null
		hinchas = new ArrayList()
		pagos = new ArrayList()
	}

	String toString(){
		"${evento} - Desde ${origen} hasta: ${destino}"
	}

	def puedeEditar(usuarioLogueado){
		if (estado.equals(Estado.cerrado()) || estado.equals(Estado.eliminado())) {
			return false
		}
		if (usuarioCreador.equals(usuarioLogueado)){
			return true
		}
	}

	def guardar(){
		//TODO: Agregar a log de modificaciones
		if (!this.estado){
			this.estado = Estado.abierto()
		}
	}

	public cerrar(){
		//TODO: Agregar a log de modificaciones
		this.fechaFinalizacion = new Date()
		this.estado = Estado.cerrado()
	}

	public retirar(){
		//TODO: Agregar a log de modificaciones
		this.fechaPublicacion = null
		this.estado = Estado.abierto()
	}

	public validar(){
		if (!this.origen || this.origen.equals("")){
			this.errors.rejectValue("origen", 'default.blank.origen')
		}else{
			if (this.origen.size() < 10) {
				this.errors.reject ("El origen debe medir al menos 10 caracteres")
			}
			if (this.origen.size() > 250) {
				this.errors.reject ("El origen no debe exceder los 250 caracteres")
			}
		}

		if (!this.destino || this.destino.equals("")){
			this.errors.rejectValue("destino", 'default.blank.destino')
		}else{
			if (this.destino.size() < 10) {
				this.errors.reject ("El destino debe medir al menos 10 caracteres")
			}
			if (this.destino.size() > 250) {
				this.errors.reject ("El destino no debe exceder los 250 caracteres")
			}
		}

		return this.errors.errorCount == 0
	}

	def agregarComentario(comentario){
		this.addToComentarios(comentario)
	}

	def eliminarComentario(comentario){
		this.removeFromComentarios(comentario)
	}

	public estaPublicada(){
		return fechaPublicacion != null && estado.equals(Estado.abierto())
	}
	
	public estaEliminado(){
		return fechaEliminacion != null && estado.equals(Estado.eliminado())
	}

	def traerDatosRelacionados() {
		hinchas?.each { usuario ->
			usuario.traerDatosRelacionados()
		}
	}

	boolean esElUsuarioCreador(usuarioLogueado){
		return this.usuarioCreador.equals(usuarioLogueado)
	}

	boolean puedeEditarViaje(usuarioLogueado){
		if (estado.equals(Estado.cerrado())) {
			return false
		}
		if (esElUsuarioCreador(usuarioLogueado)){
			return true
		}
	}

	boolean tieneHinchas(){
		return !hinchas?.isEmpty() // && !esBorador()
	}

	def unirUsuario(usuario){
		this.addToHinchas(usuario)
	}
	
	def desunirUsuario(usuario){
		this.removeFromHinchas(usuario)
	}

	def puedeUnirse(usuario){
//		return this.usuarioCreador.estaBloqueado(usuario) && !estaUnido(usuario) && estaActivo() && hayAsientosDisponibles()
		println "puedeUnirse: ${this.usuarioCreador}"
		return !estaUnido(usuario) && estaActivo() && hayAsientosDisponibles()
	}
	
	def puedeDesunirse(usuario){
		return estaUnido(usuario) && estaActivo()
	}
	
	def estaActivo(){
		estado.equals(estado.abierto())
	}
	
	def hayAsientosDisponibles(){
		return asientosLibres > 0
	}
	
	def getAsientosLibres(){
		(asientosDisponibles - hinchas.size()) as int
	}
	
	def estaUnido(usuario){
		if (!usuario){
			return false
		}
		return hinchas.find{hincha->usuario.id==hincha.id } != null
	}
	
	def agregarPago(pago){
		this.addToPagos(pago)
	}

	def eliminarPago(pago){
		this.removeFromPagos(pago)
	}
	
	public eliminar(){
		this.fechaEliminacion = new Date()
		this.estado = Estado.eliminado()
	}
	
	public obtenerPago(usuario){
		println "this.pagos: ${this.pagos}"
		println "tusuario: ${usuario}"
		def pago = this.pagos.find{it.usuario.equals(usuario)}
		println "pago recuperado: ${pago}"
		return pago
	}


}
